#include "MLadderStepSlider.h"

#include <QDebug>
#include <QMouseEvent>
#include <QPainter>
#include <QPainterPath>
#include <QtGlobal>

#include <algorithm>

const int SLIDER_HEIGHT = 10;
const int RADIUS = 4;

MLadderStepSlider::MLadderStepSlider(QWidget *parent) : QWidget(parent)
{
    setMouseTracking(true);
    setDefaultStyle();
    setFocusPolicy(Qt::StrongFocus);
}

void MLadderStepSlider::setRange(int min, int max)
{
    maxValue_ = max;
    minValue_ = min;
}

int MLadderStepSlider::minimum() const
{
    return minValue_;
}

int MLadderStepSlider::maximum() const
{
    return maxValue_;
}

void MLadderStepSlider::setValue(int value)
{
    if (value >= minValue_ && value <= maxValue_ && !isDragable)
    {
        lastValue_ = curValue_;
        curValue_ = value;
        update();
    }
}

int MLadderStepSlider::value() const
{
    return curValue_;
}

void MLadderStepSlider::setDefaultValue(int value)
{
    if (value >= minValue_ && value <= maxValue_)
    {
        defaultValue_ = value;
    }
    else
    {
        defaultValue_ = 0;
    }
}

void MLadderStepSlider::setEnableHandleAnimation(bool isEnable, int borderMaxWidth)
{
    handleAnimationEnable_ = isEnable;
    borderMaxWidth_ = borderMaxWidth;
    createAnimation();
}

void MLadderStepSlider::setSingleStep(int step)
{
    singleStep_ = step;
}

void MLadderStepSlider::setStepRules(const std::vector<std::tuple<int, int, int, int>> &rulesTuple)
{
    sliderStepRulesTuple_ = rulesTuple;
}

void MLadderStepSlider::setEventEnable(bool isEnable)
{
    eventEnable_ = isEnable;
}

void MLadderStepSlider::setHoverState(bool isHover)
{
    if (!isEnabled() || eventEnable_)
    {
        return;
    }
    isHovered = isHover;
    recalculateRectangle();
    update();
}

bool MLadderStepSlider::isChangeValueIng()
{
    return isDragable;
}

void MLadderStepSlider::setText(const QString &text, int flag)
{
    sliderTextContent_ = text;
    textAlignmentFlag_ = flag;
}

void MLadderStepSlider::setTextStyle(const QFont &font, const QColor &color, StateStyle state)
{
    switch (state)
    {
    case STYLE_NORMAL:
        textFont_ = font;
        textColor_ = color;
        textHoverFont_ = font;
        textHoverColor_ = color;
        textDisableFont_ = font;
        textDisableColor_ = color;
        break;
    case STYLE_HOVER:
        textHoverFont_ = font;
        textHoverColor_ = color;
        break;
    case STYLE_DISABLE:
        textDisableFont_ = font;
        textDisableColor_ = color;
        break;
    }
}

void MLadderStepSlider::setBgStyle(const QColor &color, StateStyle state)
{
    switch (state)
    {
    case STYLE_NORMAL:
        sliderBgColor_ = color;
        sliderBgHoverColor_ = color;
        sliderBgDisableColor_ = color;
        break;
    case STYLE_HOVER:
        sliderBgHoverColor_ = color;
        break;
    case STYLE_DISABLE:
        sliderBgDisableColor_ = color;
        break;
    }
}

void MLadderStepSlider::setGrooveBgStyle(int height, int radius, const QList<QColor> &colorList, StateStyle state)
{
    switch (state)
    {
    case STYLE_NORMAL:
        sliderGrooveHeight_ = height;
        sliderGrooveRadius_ = radius;
        sliderGrooveBgColorList_ = colorList;

        sliderGrooveHoverHeight_ = height;
        sliderGrooveHoverRadius_ = radius;
        sliderGrooveHoverBgColorList_ = colorList;

        sliderGrooveDisableHeight_ = height;
        sliderGrooveDisableRadius_ = radius;
        sliderGrooveDisableBgColorList_ = colorList;
        break;
    case STYLE_HOVER:
        sliderGrooveHoverHeight_ = height;
        sliderGrooveHoverRadius_ = radius;
        sliderGrooveHoverBgColorList_ = colorList;
        break;
    case STYLE_DISABLE:
        sliderGrooveDisableHeight_ = height;
        sliderGrooveDisableRadius_ = radius;
        sliderGrooveDisableBgColorList_ = colorList;
        break;
    }
}

void MLadderStepSlider::setSubPageBgStyle(const QList<QColor> &colorList, StateStyle state)
{
    switch (state)
    {
    case STYLE_NORMAL:
        sliderSubPageBgColorList_ = colorList;
        sliderSubPageHoverBgColorList_ = colorList;
        sliderSubPageDisableBgColorList_ = colorList;
        break;
    case STYLE_HOVER:
        sliderSubPageHoverBgColorList_ = colorList;
        break;
    case STYLE_DISABLE:
        sliderSubPageDisableBgColorList_ = colorList;
        break;
    }
}

void MLadderStepSlider::setHandleBgStyle(int width, int height, int radius, const QColor &color, StateStyle state)
{
    switch (state)
    {
    case STYLE_NORMAL:
        sliderHandleWidth_ = width;
        sliderHandleHeight_ = height;
        sliderHandleRadius_ = radius;
        sliderHandleBgColor_ = color;

        sliderHandleHoverWidth_ = width;
        sliderHandleHoverHeight_ = height;
        sliderHandleHoverRadius_ = radius;
        sliderHandleHoverBgColor_ = color;

        sliderHandleDisableWidth_ = width;
        sliderHandleDisableHeight_ = height;
        sliderHandleDisableRadius_ = radius;
        sliderHandleDisableBgColor_ = color;
        break;
    case STYLE_HOVER:

        sliderHandleHoverWidth_ = width;
        sliderHandleHoverHeight_ = height;
        sliderHandleHoverRadius_ = radius;
        sliderHandleHoverBgColor_ = color;
        break;
    case STYLE_DISABLE:

        sliderHandleDisableWidth_ = width;
        sliderHandleDisableHeight_ = height;
        sliderHandleDisableRadius_ = radius;
        sliderHandleDisableBgColor_ = color;
        break;
    }
}

void MLadderStepSlider::setHandleBorderStyle(int width, const QColor &color, StateStyle state)
{
    switch (state)
    {
    case STYLE_NORMAL:
        sliderHandleBorderColor_ = color;
        sliderHandleBorderWidth_ = width;

        sliderHandleHoverBorderColor_ = color;
        sliderHandleHoverBorderWidth_ = width;

        sliderHandleDisableBorderColor_ = color;
        sliderHandleDisableBorderWidth_ = width;
        break;
    case STYLE_HOVER:
        sliderHandleHoverBorderColor_ = color;
        sliderHandleHoverBorderWidth_ = width;
        break;
    case STYLE_DISABLE:
        sliderHandleDisableBorderColor_ = color;
        sliderHandleDisableBorderWidth_ = width;
        break;
    }
}

void MLadderStepSlider::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    drawSliderBg(&painter);
    drawSliderGroove(&painter);
    drawSliderSubPage(&painter);
    drawSliderHandle(&painter);
    drawSliderText(&painter);
}

void MLadderStepSlider::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    recalculateRectangle();
}

void MLadderStepSlider::showEvent(QShowEvent *event)
{
    QWidget::showEvent(event);
    recalculateRectangle();
}

void MLadderStepSlider::mousePressEvent(QMouseEvent *event)
{
    if (event->button() & Qt::LeftButton && sliderMouseRect.contains(event->pos()))
    {
        isDragable = true;
        if (!sliderHandleRect.contains(event->pos()))
        {
            curValue_ = calculateCurValue(event->pos().x());
            mouseFirstPressedOnHandle_ = false;
            update();
        }
        else
        {
            mouseFirstPressedOnHandle_ = true;
            emit sliderHandlePress(curValue_);
        }

        stopAnimation(zoomOutAnimation_);
        startAnimation(zoomInAnimation_);
    }
    QWidget::mousePressEvent(event);
}

void MLadderStepSlider::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && isDragable)
    {
        isDragable = false;
        if (lastValue_ != curValue_)
        {
            emit valueChanged(curValue_);
        }

        stopAnimation(zoomInAnimation_);
        startAnimation(zoomOutAnimation_);
        sliderHandleRelease(curValue_);
    }
    QWidget::mouseReleaseEvent(event);
}

void MLadderStepSlider::mouseMoveEvent(QMouseEvent *event)
{
    // if (isDragable && sliderBgRect.contains(event->pos()))
    if (isDragable)
    {
        curValue_ = calculateCurValue(event->pos().x());
        emit valueChanging(curValue_);
        update();
    }
    this->setCursor(sliderMouseRect.contains(event->pos()) ? Qt::PointingHandCursor : Qt::ArrowCursor);
    QWidget::mouseMoveEvent(event);
}

void MLadderStepSlider::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->button() & Qt::LeftButton && sliderHandleRect.contains(event->pos()) && mouseFirstPressedOnHandle_)
    {
        curValue_ = defaultValue_;
        lastValue_ = curValue_;
        emit valueChanged(curValue_);
        this->update();
    }
    mouseFirstPressedOnHandle_ = false;

    QWidget::mouseDoubleClickEvent(event);
}

void MLadderStepSlider::enterEvent(QEvent *event)
{
    QWidget::enterEvent(event);
    if (eventEnable_)
    {
        isHovered = true;
        recalculateRectangle();
        update();
    }
}

void MLadderStepSlider::leaveEvent(QEvent *event)
{
    QWidget::leaveEvent(event);
    if (eventEnable_)
    {
        isHovered = false;
        recalculateRectangle();
        update();
    }
}

void MLadderStepSlider::keyPressEvent(QKeyEvent *event)
{
    auto newValue = curValue_;
    switch (event->key())
    {
    case Qt::Key_Down:
        newValue = calculateChangedValue(false);
        break;
    case Qt::Key_Up:
        newValue = calculateChangedValue(true);
        break;
    }

    if (newValue != curValue_)
    {
        curValue_ = newValue;
        emit valueChanging(newValue);
        update();
    }
}

void MLadderStepSlider::keyReleaseEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)
    {
        emit valueChanged(curValue_);
    }
}

void MLadderStepSlider::wheelEvent(QWheelEvent *e)
{
    if (!hasFocus() || !sliderMouseRect.contains(e->pos()))
    {
        return;
    }

    int newValue = curValue_;
    if (e->delta() > 10)
    {
        newValue = calculateChangedValue(true);
    }
    else if (e->delta() <= -10)
    {
        newValue = calculateChangedValue(false);
    }

    if (newValue != curValue_)
    {
        curValue_ = newValue;
        emit valueChanging(newValue);
        update();
    }
    e->accept();
}

void MLadderStepSlider::drawSliderBg(QPainter *painter)
{
    const auto &bgColor = isEnabled() ? (isHovered ? sliderBgHoverColor_ : sliderBgColor_) : sliderBgDisableColor_;

    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(bgColor);
    painter->drawRect(sliderBgRect);
    painter->restore();
}

void MLadderStepSlider::drawSliderGroove(QPainter *painter)
{
    painter->save();
    const auto &bgColorList = isEnabled() ? (isHovered ? sliderGrooveHoverBgColorList_ : sliderGrooveBgColorList_) : sliderGrooveDisableBgColorList_;
    const auto &radius = isEnabled() ? (isHovered ? sliderGrooveHoverRadius_ : sliderGrooveRadius_) : sliderGrooveDisableRadius_;

    painter->setPen(Qt::NoPen);
    if (bgColorList.size() > 1)
    {
        QLinearGradient gradient(0, 0, width(), height());
        auto step = 1.0f / static_cast<float>(bgColorList.size() - 1);
        for (int i = 0; i < bgColorList.size(); i++)
        {
            gradient.setColorAt(static_cast<float>(i) * step, bgColorList[i]); // 渐变起始颜色
        }

        painter->setBrush(gradient);
        painter->drawRoundedRect(sliderGrooveRect, radius, radius);
    }
    else if (bgColorList.size() == 1)
    {
        painter->setBrush(bgColorList[0]);
        painter->drawRoundedRect(sliderGrooveRect, radius, radius);
    }
    else
    {
        painter->setBrush(QColor(100, 100, 100));
        painter->drawRoundedRect(sliderGrooveRect, radius, radius);
    }

    if (minValue_ < 0 && maxValue_ > 0)
    {
        const auto &color = isEnabled() ? (isHovered ? sliderZeroScaleColorList_[1] : sliderZeroScaleColorList_[0]) : sliderZeroScaleColorList_[2];
        painter->setBrush(QBrush(color));
        painter->setPen(Qt::NoPen);
        auto posX = (sliderBgRect.width() - 2) * ((double)abs(minValue_) / (double)(maxValue_ - minValue_));
        auto posY = (sliderBgRect.height() - 6) / 2;
        painter->drawRoundedRect(posX, posY, 2, 6, 1, 1);
    }

    painter->restore();
}

void MLadderStepSlider::drawSliderSubPage(QPainter *painter)
{
    painter->save();

    QRectF subPageRect(sliderGrooveRect);

    auto width = 0.0;
    auto posX = 0.0;
    if (minValue_ < 0 && maxValue_ > 0)
    {
        width = sliderIncrement * abs(curValue_);
        posX = curValue_ <= 0 ? sliderIncrement * (curValue_ - minValue_) : sliderGrooveRect.left() + sliderIncrement * abs(minValue_);
    }
    else
    {
        auto point = calculateSliderHandlePos();
        width = point.x();
    }
    subPageRect.setX(posX);
    subPageRect.setWidth(width);

    const auto &colorList = isEnabled() ? (isHovered ? sliderSubPageHoverBgColorList_ : sliderSubPageBgColorList_) : sliderSubPageDisableBgColorList_;
    const auto &radius = isEnabled() ? (isHovered ? sliderGrooveHoverRadius_ : sliderGrooveRadius_) : sliderGrooveDisableRadius_;

    if (!colorList.isEmpty())
    {
        const QColor &color = colorList.size() == 1 ? colorList[0] : (curValue_ < 0 ? colorList[0] : colorList[1]);

        if (color.isValid())
        {
            painter->setPen(Qt::NoPen);
            painter->setBrush(color);
            if (minValue_ < 0 && maxValue_ > 0)
            {
                painter->drawRect(subPageRect);
            }
            else
            {
                painter->drawRoundedRect(subPageRect, radius, radius);
            }
        }
    }

    painter->restore();
}

void MLadderStepSlider::drawSliderHandle(QPainter *painter)
{
    painter->save();
    sliderHandleRect.moveTo(calculateSliderHandlePos());

    const auto &borderColor = isEnabled() ? (isHovered ? sliderHandleHoverBorderColor_ : sliderHandleBorderColor_) : sliderHandleDisableBorderColor_;
    const auto &bgColor = isEnabled() ? (isHovered ? sliderHandleHoverBgColor_ : sliderHandleBgColor_) : sliderHandleDisableBgColor_;
    const auto &radius = isEnabled() ? (isHovered ? sliderHandleHoverRadius_ : sliderHandleRadius_) : sliderHandleDisableRadius_;
    double borderWidth = isEnabled() ? (isHovered ? sliderHandleHoverBorderWidth_ : sliderHandleBorderWidth_) : sliderHandleDisableBorderWidth_;

    if (handleAnimationEnable_ && isDragable)
    {
        borderWidth = curHandleBorderWidth_;
    }

    painter->setPen(Qt::NoPen);
    painter->setBrush(bgColor);
    painter->drawRoundedRect(sliderHandleRect, radius, radius);

    painter->setBrush(borderColor);
    QPainterPath rectPath;
    QPainterPath circlePath;
    rectPath.addRoundedRect(sliderHandleRect, radius, radius);
    circlePath.addRoundedRect(sliderHandleRect.adjusted(curHandleBorderWidth_, curHandleBorderWidth_, -curHandleBorderWidth_, -curHandleBorderWidth_), radius,
                              radius);
    painter->drawPath(rectPath - circlePath);
    painter->restore();
}

void MLadderStepSlider::drawSliderText(QPainter *painter)
{
    if (sliderTextContent_.isEmpty())
    {
        return;
    }
    painter->save();

    const auto &font = isEnabled() ? (isHovered ? textHoverFont_ : textFont_) : textDisableFont_;
    const auto &color = isEnabled() ? (isHovered ? textHoverColor_ : textColor_) : textDisableColor_;

    QPen pen;
    pen.setColor(color);
    painter->setPen(pen);
    painter->setFont(font);
    painter->setBrush(Qt::NoBrush);
    //    painter->drawText(sliderBgRect, sliderTextContent_, QTextOption(Qt::AlignVCenter | Qt::AlignLeft));
    painter->drawText(sliderBgRect, sliderTextContent_, QTextOption(static_cast<Qt::Alignment>(textAlignmentFlag_)));

    painter->restore();
}

void MLadderStepSlider::recalculateRectangle()
{
    const auto &grooveHeight = isEnabled() ? (isHovered ? sliderGrooveHoverHeight_ : sliderGrooveHeight_) : sliderGrooveDisableHeight_;
    const auto &handleHeight = isEnabled() ? (isHovered ? sliderHandleHoverHeight_ : sliderHandleHeight_) : sliderHandleDisableHeight_;
    const auto &handleWidth = isEnabled() ? (isHovered ? sliderHandleHoverWidth_ : sliderHandleWidth_) : sliderHandleDisableWidth_;
    const auto &grooveOffset = static_cast<double>(sliderBgRect.height() - grooveHeight) / 2.0f;
    const auto &handleOffset = static_cast<double>(sliderBgRect.height() - handleHeight) / 2.0f;

    sliderBgRect = this->rect();
    sliderGrooveRect = sliderBgRect.adjusted(1, grooveOffset, -1, -grooveOffset);
    sliderHandleRect = QRectF(0, handleOffset, handleWidth, handleHeight);
    sliderMouseRect = QRectF(0, handleOffset, sliderBgRect.width(), qMax(handleHeight, grooveHeight));

    sliderIncrement = static_cast<double>(sliderGrooveRect.width()) / (maxValue_ - minValue_);

    QRectF rectF = QRectF(sliderMouseRect.left(), sliderMouseRect.top(), 0, sliderMouseRect.height());
    const auto &&sliderWidth = sliderGrooveRect.width();

    sliderMappingTuple_.clear();
    double posX = {0.0};
    double posY = {0.0};
    for (const auto &tuple : sliderStepRulesTuple_)
    {
        double width = sliderWidth * std::get<3>(tuple) / 100;
        posX = posY;
        posY = posX + width;
        double increment = width / static_cast<double>(std::get<1>(tuple) - std::get<0>(tuple));
        sliderMappingTuple_.push_back({std::get<0>(tuple), std::get<1>(tuple), posX, posY, increment});
    }
}

QPointF MLadderStepSlider::calculateSliderHandlePos()
{
    const auto &handleWidth = isEnabled() ? (isHovered ? sliderHandleHoverWidth_ : sliderHandleWidth_) : sliderHandleDisableWidth_;
    double handlePos = {0.0};
    for (const auto &tuple : sliderMappingTuple_)
    {
        const auto &start = std::get<0>(tuple);
        const auto &end = std::get<1>(tuple);
        const auto &posX = std::get<2>(tuple);
        const auto &posY = std::get<3>(tuple);
        const auto &step = std::get<4>(tuple);
        if (curValue_ >= start && curValue_ <= end)
        {
            handlePos = posX + step * (curValue_ - start) - static_cast<double>(handleWidth) / 2.0f;
            break;
        }
    }

    handlePos = qBound(sliderGrooveRect.left(), handlePos, sliderGrooveRect.right() - handleWidth);
    return {handlePos, sliderHandleRect.y()};
}

int MLadderStepSlider::calculateCurValue(int mousePosX)
{
    int value = curValue_;

    // 第一个循环：根据鼠标位置计算初始值
    for (const auto &tuple : sliderMappingTuple_)
    {
        const auto [start, end, posX, posY, step] = tuple; // 使用结构化绑定
        if (mousePosX >= posX && mousePosX <= posY)
        {
            value = start + static_cast<int>((mousePosX - posX) / step);
            break; // 找到对应区间后，退出循环
        }
    }

    // 第二个循环：根据规则调整值
    for (const auto &tuple : sliderStepRulesTuple_)
    {
        const auto [start, end, step, ratio] = tuple; // 使用结构化绑定
        if (value >= start && value < end)
        {
            // 计算修正后的值
            // clang-format off
            value = (value > curValue_)
                        ? std::ceil(value / static_cast<double>(step)) * step
                        : std::floor(value / static_cast<double>(step)) * step;
            // clang-format on
            break; // 找到对应规则后，退出循环
        }
    }

    // 确保值在合法范围内
    return qBound(minValue_, value, maxValue_);
}

void MLadderStepSlider::setDefaultStyle()
{
    // 滑动条 三态 背景颜色
    sliderBgColor_ = QColor(0, 0, 0, 0);
    sliderBgHoverColor_ = QColor(0, 0, 0, 0);
    sliderBgDisableColor_ = QColor(0, 0, 0, 0);

    // 滑动条 滑轨 正常背景颜色、 高度、圆角
    sliderGrooveBgColorList_ = {QColor(255, 255, 255, 38)};
    sliderGrooveHeight_ = 2;
    sliderGrooveRadius_ = 1;

    // 滑动条 滑轨 高亮背景颜色、 高度、圆角
    sliderGrooveHoverBgColorList_ = {QColor(255, 255, 255, 38)};
    sliderGrooveHoverHeight_ = 2;
    sliderGrooveHoverRadius_ = 1;

    // 滑动条 滑轨 禁用背景颜色、 高度、圆角
    sliderGrooveHoverBgColorList_ = {QColor(255, 255, 255, 38)};
    sliderGrooveDisableHeight_ = 2;
    sliderGrooveDisableRadius_ = 1;

    // 滑动条 三态 背景颜色
    sliderSubPageBgColorList_ = {QColor(255, 255, 255, 200), QColor(255, 255, 255, 200)};
    sliderSubPageHoverBgColorList_ = {QColor(255, 255, 255), QColor(255, 255, 255)};
    sliderSubPageDisableBgColorList_ = {QColor(255, 255, 255, 153), QColor(255, 255, 255, 153)};

    sliderZeroScaleColorList_ = {QColor("#D2D2D2"), QColor("#FFFFFF"), QColor("#D2D2D2")};

    sliderHandleBgColor_ = QColor(0, 0, 0);
    sliderHandleWidth_ = 12;
    sliderHandleHeight_ = 12;
    sliderHandleRadius_ = 6;

    sliderHandleHoverBgColor_ = QColor(0, 0, 0);
    sliderHandleHoverWidth_ = 12;
    sliderHandleHoverHeight_ = 12;
    sliderHandleHoverRadius_ = 6;

    sliderHandleDisableBgColor_ = QColor(0, 0, 0);
    sliderHandleDisableWidth_ = 12;
    sliderHandleDisableHeight_ = 12;
    sliderHandleDisableRadius_ = 6;

    sliderHandleBorderColor_ = QColor(255, 255, 255, 200);
    sliderHandleBorderWidth_ = 2;

    sliderHandleHoverBorderColor_ = QColor(255, 255, 255);
    sliderHandleHoverBorderWidth_ = 2;

    sliderHandleDisableBorderColor_ = QColor(255, 255, 255, 153);
    sliderHandleDisableBorderWidth_ = 2;
}

void MLadderStepSlider::createAnimation()
{
    if (!zoomOutAnimation_)
    {
        zoomOutAnimation_ = new QPropertyAnimation(this, "curHandleBorderWidth_", this);
        zoomOutAnimation_->setStartValue(borderMaxWidth_);
        zoomOutAnimation_->setEndValue(sliderHandleHoverBorderWidth_);
        // 设置动画的持续时间和缓动曲线
        zoomOutAnimation_->setDuration(100);
        zoomOutAnimation_->setEasingCurve(QEasingCurve::InOutQuad);

        connect(zoomOutAnimation_, &QPropertyAnimation::valueChanged, this, [=](const QVariant &value) {
            this->curHandleBorderWidth_ = value.toDouble();
            update();
        });
    }

    if (!zoomInAnimation_)
    {
        zoomInAnimation_ = new QPropertyAnimation(this, "curHandleBorderWidth_", this);
        zoomInAnimation_->setStartValue(sliderHandleHoverBorderWidth_);
        zoomInAnimation_->setEndValue(borderMaxWidth_);
        // 设置动画的持续时间和缓动曲线
        zoomInAnimation_->setDuration(100);
        zoomInAnimation_->setEasingCurve(QEasingCurve::InOutQuad);

        connect(zoomInAnimation_, &QPropertyAnimation::valueChanged, this, [=](const QVariant &value) {
            this->curHandleBorderWidth_ = value.toDouble();
            update();
        });
    }
}

void MLadderStepSlider::startAnimation(QPropertyAnimation *animation)
{
    if (animation && animation->state() != QAbstractAnimation::Running)
    {
        animation->start();
    }
}

void MLadderStepSlider::stopAnimation(QPropertyAnimation *animation)
{
    if (animation && animation->state() == QAbstractAnimation::Running)
    {
        animation->stop();
    }
}

int MLadderStepSlider::calculateChangedValue(bool isRise)
{
    int cruStep = 1;
    int newValue = curValue_;

    // 找到对应的步长
    for (const auto &tuple : sliderStepRulesTuple_)
    {
        const auto [start, end, step, ratio] = tuple; // 使用结构化绑定
        if ((isRise && curValue_ >= start && curValue_ < end) || (!isRise && curValue_ > start && curValue_ <= end))
        {
            cruStep = step;
            break;
        }
    }

    // 根据 isRise 决定新值
    if (isRise)
    {
        newValue = (curValue_ % cruStep == 0) ? curValue_ + cruStep : std::ceil(static_cast<double>(curValue_) / cruStep) * cruStep;
        newValue = qMin(newValue, maxValue_);
    }
    else
    {
        newValue = (curValue_ % cruStep == 0) ? curValue_ - cruStep : std::floor(static_cast<double>(curValue_) / cruStep) * cruStep;
        newValue = qMax(newValue, minValue_);
    }

    return newValue;
}
